﻿using System;
using Microsoft.WindowsAzure;

//using System.Diagnostics;

namespace FLH.RegionDataAllocations
{
	/// <summary>
	/// Initialize the Azure Tables. This should be called from your WebRole.cs OnStart method
	/// after all other initializations and immediately prior to the base.OnStart() call.
	/// </summary>
	public class AzureTableInitialization
	{
		// **** SEE EXAMPLE USAGE BELOW TO INITIALIZE THE TABLES ***

		// Recommended in the final build that your table name should be set to a constant particularly
		// if the table will exist for a long time like in a SQL database where table names rarely
		// ever are changed.  This should then prevent accidential name changes on production tables
		// while allowing development subsequent to production releases.

		/// <summary>
		/// This is one and only AzureTableDataConnectionString. Do not remove.
		/// The public version is located in AllocationsServiceContext.
		/// </summary>
		internal static string AzureTableDataConnectionString;
		/// <summary>
		/// This is one and only AllocationsTableName. Do not remove.
		/// The public version is located in AllocationsServiceContext.
		/// </summary>
		internal static string AllocationsTableName;

		// In production code UNcomment line and then set the literals to the desired values.
		// Optionally, use the dynamic setting from the WebRole.cs
		//internal const string AzureTableDataConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";

		// If you want to hard code the table name, replace the empty string with a valid Azure table
		// name. CAUTION! will override any other setting if it is not empty.
		// See table storage Azure contraints: http://msdn.microsoft.com/en-us/library/dd179338.aspx
		// Table names must conform to these rules:
		//	Table names may contain only alphanumeric characters.
		//	A table name may not begin with a numeric character. 
		//	Table names are case-insensitive.
		//	Table names must be from 3 through 63 characters long.
		internal const string HardCodeTableName = "Allocations";

		private static bool _isCloudApplication = true;
		/// <summary>
		/// Gets or sets a value indicating whether this implementation is in a cloud application.
		/// If it is not as when the appliation is a console app then this must be set to
		/// false or it will throw a storage client error on initialize of tables.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is cloud application; otherwise, <c>false</c>.
		/// </value>
		public static bool IsCloudApplication
		{
			get { return _isCloudApplication; }
			set { _isCloudApplication = value; }
		}

		/// <summary>
		/// Gets or sets the Azure storage account name.
		/// </summary>
		/// <value>The name of the account.</value>
		public static string AccountName { get; set; }
		/// <summary>
		/// Gets or sets the Azure storage account key.
		/// </summary>
		/// <value>The account key.</value>
		public static string AccountKey { get; set; }

		/// <summary>
		/// This method is used if you are not initializing tables and you are not even checking for
		/// table existance.  You must set the connection and table name for the data context.
		/// </summary>
		/// <param name="azureDataConnectionString"></param>
		/// <param name="azureTableName"></param>
		public static void SetAzureTableContextDefaults(string azureDataConnectionString)
		{
			try
			{
				AzureTableDataConnectionString = azureDataConnectionString;
				AllocationsTableName = HardCodeTableName;

				if (String.IsNullOrEmpty(AzureTableDataConnectionString))
				{
					throw new NullReferenceException(
						"The azure DataConnectionString is missing or there is no table name given. Additionally the DataConnectionString must match your service configuration.");
				}
			}
			catch (NullReferenceException)  //(NullReferenceException nullReferenceException)
			{
				//Debug.Assert(false, nullReferenceException.Message);			
			}
		}

		public static CloudStorageAccount GetAccount()
		{
			if (String.IsNullOrEmpty(AzureTableDataConnectionString)) return null;

			if (_isCloudApplication)
				return CloudStorageAccount.FromConfigurationSetting(AzureTableDataConnectionString);

			// Create the account object using application settings
			var credentials = new StorageCredentialsAccountAndKey(AccountName, AccountKey);
			return new CloudStorageAccount(credentials, true);
		}

	}
}
